# -*- coding: utf-8 -*-
from __future__ import unicode_literals

import hashlib
from collections import OrderedDict


class Link(object):
    """链接解析"""
    def __init__(self, content, paragraph_index, escape_char='\\'):
        super(Link, self).__init__()
        self.content = content
        self.cache_key = 'link'
        self.paragraph_index = paragraph_index
        self.escape_char = escape_char

    @property
    def states(self):
        return {
            'normal': 0, # init, cache -->
            'begin': 1, # normal --> <
            'cache': 2, # begin --> [^<>]
            'ignore': 3
        }

    def _getStateKey(self, state):
        '''根据状态值获取状态键'''
        for _k in self.states:
            if state == self.states[_k]:
                return _k

    def _removeEscape(self, content):
        '''移除转义'''
        _tmp = content
        for _ch in ['<', ':', '>']:
            _tmp = _tmp.replace(self.escape_char + _ch, _ch)
        return _tmp

    def _toHtml(self, content):
        '''转化为html'''
        _arr = self._checkSyntax(content)
        _title = _arr[0]
        _href = _arr[1]
        if _href.startswith('!'):
            _href = _href[1:]
            if not bool(_title):
                _title = _href
            _content = '<img src="' + _href + '" title="' + _title + '" alt="' + _title + '" />'
        else:
            if _href.endswith('#') and len(_href) > 1:
                _href = _href[:-1]
                if not bool(_title):
                    _title = _href
                _content = '<span class="rmk-anchor-define" id="' + _href + '">' + _title + '</span>'
            else:
                _target = '_self'
                if _href.endswith('@'):
                    _href = _href[:-1]
                    _target = '_blank'
                if not bool(_title):
                    _title = _href
                    if _title.startswith('#'):
                        _title = _title[1:]
                _content = '<a target="' + _target + '" href="' + _href + '">' + _title + '</a>'
        return self._removeEscape(_content)

    def _wrapperResult(self, cache):
        '''包装解析结果'''
        ret = {
            'content': self.content,
            'cache': {}
        }
        if bool(cache):
            _tmp = []
            _cache = {}
            _begin = 0
            for _k in cache:
                _v = cache[_k]
                _cache[_k] = self._toHtml(_v['content'][1:-1])
                _c = self.content[_begin : _v['start']]
                _tmp.append(_c)
                _tmp.append(_k)
                _begin = _v['end']
            if _begin < len(self.content):
                _c = self.content[_begin:]
                _tmp.append(_c)
            ret['content'] = ''.join(_tmp)
            ret['cache'] = _cache
        return ret

    def _checkSyntax(self, content):
        '''语法检查'''
        _arr = content.split('::')
        if len(_arr) != 2 or not bool(_arr[1]):
            raise SyntaxError('link or anchor syntax error')
        return _arr

    def parse(self):
        '''执行解析操作'''
        # init state is normal
        state = self.states['normal']
        i = 0
        start = None
        end = None
        store = OrderedDict()
        while i < len(self.content):
            _c = self.content[i]
            if _c == '<':
                if state == self.states['normal']:
                    state = self.states['begin']
                    start = i
                elif state == self.states['begin']:
                    start = i
                elif state == self.states['ingore']:
                    state = self.states['cache']
                elif state == self.states['cache']:
                    state = self.states['begin']
                    start = i
            elif _c == '>':
                if state == self.states['normal']:
                    pass
                elif state == self.states['begin']:
                    state = self.states['normal']
                elif state == self.states['ignore']:
                    state = self.states['cache']
                elif state == self.states['cache']:
                    state = self.states['normal']
                    end = i + 1
                    if not start is None and not end is None:
                        if end - start > 3:
                            _k = '@{0}_[{1}_{2}_{3}]'.format(
                                self.cache_key,
                                str(self.paragraph_index),
                                str(start),
                                str(end)
                            )
                            try:
                                _k_md5 = hashlib.md5(_k).hexdigest()
                            except Exception as ex:
                                _k_md5 = hashlib.md5(_k.encode('utf-8', 'ignore')).hexdigest()
                            _k = '{0}{{{1}}}'.format(
                                '$',
                                _k_md5
                            )
                            _content = self.content[start : end]
                            if '::' in _content:
                                store[_k] = {
                                    'content': _content,
                                    'start': start,
                                    'end': end
                                }
                    start = None
                    end = None
            else:
                if state == self.states['cache'] or state == self.states['ignore']:
                    if _c == self.escape_char:
                        state = self.states['ignore']
                elif state == self.states['begin']:
                    state = self.states['cache']
            i += 1
        return self._wrapperResult(store)